//////////////////////////////
OAM data has 0x5800 bytes allocated to it

0x020041C8 - ram load of left to right OAM

0x020099C8 - ram load of right to left OAM

Frame data has 0x2A00 bytes allocated to it

0x0200F1C8 - ram load of left to right frame data

0x02011BC8 - ram load of right to left frame data
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//////////////////////////////
About hardcoded commands (0x26/0x27 and 0x47):

Right to left animation sheets are loaded to linear tile index 768 (0x300) in VRAM

Tossing (0x26/0x27):
- Sheet used is the sheet referenced by the following 0x86 command (?) and then the sheets referenced
by the 0x86 commands that are called after tossing has begun until it is terminated
- This means it is best to have the sprite to be thrown appear on all sheets of the animation
- Lasts until 01 command's wait state ends
- Sword/shield toss sprites are loaded as single 32x32 sprites from linear sheet index 0x1C

Cape flowing (0x47):
- Sheet used is the sheet referenced by the following 0x86 command
- Only one sheet needs the tiles for the cape flowing sprites
- OAM is loaded from ROM in the same format as the animation's OAM, but it is referenced
separately and isn't compressed
- Lasts until 01 command's wait state ends

Mages have their cape flowing OAM located around 0x08BB174C
The OAM for that frame begins at 0x08BB1710
0x08BB1712 is referenced when acessing 0x08BB1710's frame OAM
0x08BB1712 appears at 0x08BB17E8, which is pointed to by a seemingly unused pointer and loaded into
	registers for acessing the OAM
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//////////////////////////////
About 85 00 00 01 command customization

0x0804D574 - returns true if a hit is complete (can escape an 01 command)

.org				0x080067B2
ldr	r0,	[r2,	#0x20]	@Loads animation data interpretation offset
sub	r0,	#0x4		@Decrements animation data interpretation offset
str	r0,	[r2,	#0x20]	@Updates animation data interpretation offset
@-------------------------------@Command is in r3 as an int

@Hack allowing XX of 85 00 XX 01
@to become a word count of words to repeat
@prior to the command during HP depletion

.org				0x080067B2
nop				@0000
@-------------------------------@F0C4
@-------------------------------@FEC0
bl				0x080CB538

.org				0x080CB538
.thumb
lsl	r3,	r3,	#0x10	@041B
lsr	r3,	r3,	#0x18	@0E1B
lsl	r3,	r3,	#0x2	@009B
@-------------------------------@F782
@-------------------------------@F819
bl				0x0804D574 - 0x080CB538
cmp	r0,	#0x1		@2801
@-------------------------------@D100
bne				LOOP
mov	r3,	#0x0		@2300
LOOP:
add	r3,	r3,	#0x4	@3304
ldr	r0,	[r2,	#0x20]	@6A10
sub	r0,	r0,	r3	@1AC0
str	r0,	[r2,	#0x20]	@6210
mov	r0,	r4		@1C20
pop	{r4, r5, pc}		@BD30
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//////////////////////////////
.org				0x080517CE
ldr	r0,	[r1,	#0x4]	;Reads player attacker's standing frame data
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//////////////////////////////
Class Animation Pointer Table: 0x08E00008 to 0x08E01448

0x08F88E40 - One of the Linus sheets

Sample from pointer table:
{84 f9 e8 08 3c f8 e8 08 ec f5 e8 08 90 f3 e8 08 44 f3 e8 08}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//////////////////////////////
0x0203E026 - ram location of weapon/spell animation association value

0x08C999C0 - rom start of spell animation association per weapon table

.org				0x08055896
ldr	r1,	[pc,	#0x1C]	@=#0x08BA13D0
@-------------------------------@Spell animation PC table
mov	r2,	#0x0		@
ldsh	r0,	[r0,	r2]	@Loads spell ID
lsl	r0,	r0,	#0x2	@
add	r0,	r0,	r1	@
ldr	r1,	[r0]		@Get PC ref
mov	r0,	r5		@
bl				#0x080BFC50

.org				0x080BFC50
bx	r1			@Oh joy
nop

@-------------------------------@Sword of Seals
.org				0x0805779C
push	{r4, r5, lr}		@
mov	r5,	r0		@
bl				0x0804FFF0
@-------------------------------@Screen dimming is handled by this call
bl				0x0804FB6C
bl				0x08050008
@-------------------------------@Only difference between routines is here:
ldr	r0,	[pc,	#0x24]	@=#0x08BA1874
mov	r1,	#0x3		@
bl				0x08004494
mov	r4,	r0		@
str	r5,	[r4,	#0x5C]	@
mov	r0,	#0x0		@
strh	r0,	[r4,	#0x2C]	@
mov	r0,	r5		@
bl				0x08054804
lsl	r0,	r0,	#0x10	@
asr	r0,	r0,	#0x10	@
bl				0x0805468C
add	r4,	#0x29		@
strb	r0,	[r4]		@
pop	{r4, r5}		@
pop	{r0}			@
bx	r0			@Sword of Seals complete!

@-------------------------------@Divine
.org				0x0805AE90
push	{r4, r5, lr}		@
mov	r5,	r0		@
bl				0x0804FFF0
bl				0x0804FB6C
bl				0x08050008
@-------------------------------@Only difference between routines is here:
ldr	r0,	[pc,	#0x24]	@=#0x08BA29A8

Pointer that differs above should point to this:

Struct 0x18 bytes in size

+0x00	Word set to 0x00000019
+0x04	Word of 0
+0x08	Word set to 0x00000003
+0x0C	PC to execute
+0x10	Word of 0
+0x14	Word of 0

@-------------------------------@Sword of Seals
@-------------------------------@Comparing to Divine;
@-------------------------------@most of the time the two routines are the same
@-------------------------------@except where specified (haven't finished comparing the two)
@-------------------------------@IMPORTANT: Screen dimming is handled before this, but this routine
@-------------------------------@handles screen shifting. It is also only called a few times during
@-------------------------------@the animation; in other words, it sets up the animation in "chunks"
@-------------------------------@and is called again when the previous chunk has been processed
.org				0x080577D8
push	{r4-r7, lr}		@
add	sp,	#-0x8		@Divine doesn't do this
add	r4,	r0,	#0x0	@
ldr	r0,	[r4,	#0x5C]	@Loads pointer to AIS for unit casting this spell
bl				0x080547A8
add	r5,	r0,	#0x0	@Puts returned pointer to target unit's AIS into r5
bl				0x08050778
add	r6,	r0,	#0x0	@Divine uses r3; seems to return ID of next frame to do something
@-------------------------------@on, minus 1 (returns 0x10 for this animation)
ldrh	r0,	[r4,	#0x2C]	@Load ID of frame to execute
add	r0,	#0x1		@FrameID++
mov	r7,	#0x0		@Divine doesn't do this
strh	r0,	[r4,	#0x2C]	@FrameID++
lsl	r0,	r0,	#0x10	@
asr	r0,	r0,	#0x10	@
cmp	r0,	#0x1		@Check if frame ID is 0x01
bne				0x08057806
ldr	r0,	[r4,	#0x5C]	@From here-----
mov	r1,	#0x1		@
neg	r1,	r1		@
@-------------------------------@Scrolls the screen
bl				0x0804E498
.org				0x08057806
mov	r0,	#0x2C		@
ldsh	r1,	[r4,	r0]	@Reload current frame ID
add	r0,	r6,	#0x1	@Check if frame ID is 0x11
cmp	r1,	r0		@-----through here occurs after the difference below
bne				0x08057854
@-------------------------------@Load SoS fire music value
@-------------------------------@This frame is responsible for initializing and starting playing of
@-------------------------------@the actual animation
ldr	r0,	[pc,	#0x3C]	@=#0x0000010D
mov	r1,	#0x80		@
lsl	r1,	r1,	#0x1	@
mov	r3,	#0x2		@
ldsh	r2,	[r5,	r3]	@
mov	r3,	#0x1		@
@-------------------------------@Play music routine
bl				0x080681E4
add	r0,	r5,	#0x0	@
@-------------------------------@Divine calls 0x0805AFBC here instead;
@-------------------------------@Using Divine's call makes the first Divine shot go up (in the wrong
@-------------------------------@place, no less, because the screen will have already shifted) and the
@-------------------------------@call below makes the fire appear for this animation; not responsible
@-------------------------------@for "hitting" the enemy
@-------------------------------@This routine immediately loads pointers to streams of PCs to execute
@-------------------------------@and OAM data, calling functions after each case; also does this with 
@-------------------------------@TSA (?) and sheet pointers
bl				0x08057894
ldr	r0,	[r4,	#0x5C]	@
mov	r1,	#0x6		@Divine doesn't do this; instead, it calls
@-------------------------------@0x0805B1EC
@-------------------------------@Divine doesn't make the call below; the function below immediately
@-------------------------------@loads 0x08B9AE4C, a pointer to a vector in the format:

0x00000019 - Start
0x00000000 - NOP; terminate if next word is NOP?
0x000A000F - What?
0x00000000 - NOP
0x00000003 - Execute this routine:
0x0804F0B1 - Address to BX to

These v ^ routines seem negligible :/

0x00000003 - Execute this routine:
0x0804F0E8 - Address to BX to
0x00000000 - Terminator part 1
0x00000000 - Terminator part 2

@-------------------------------@Not sure what this routine does but seems unnecessary
bl				0x0804EFDC
mov	r0,	#0x9		@Divine doesn't do this; instead, it branches to
@-------------------------------@0x0805AFB6 (exit)
@-------------------------------@The bits in 0x09 are "hit" flags that indicate that the target has been
@Divine has:
@-------------------------------@
@.long				0x00000127
@cmp	r2,	#0x14
@bne				0x0805AF24
@Else: Play music of ID 0x0094
@-------------------------------@From here-----
ldrh	r1,	[r5,	#0x10]	@Load target's status flags
orr	r0,	r1		@Set "hit" flags that were immediately loaded
strh	r0,	[r5,	#0x10]	@Update status flags
add	r4,	#0x29		@
ldrb	r1,	[r4,	#0x0]	@
add	r0,	r5,	#0x0	@
@-------------------------------@The following routine is responsible for subtracting from the target's
@-------------------------------@health bar but is not needed to "hit" the enemy (though it looks weird
@-------------------------------@to leave this routine out >.>)
bl				0x08050140
ldrb	r0,	[r4,	#0x0]	@
cmp	r0,	#0x0		@
bne				0x0805788A
add	r0,	r5,	#0x0	@
@-------------------------------@This routine plays the "hit target" sound
@-------------------------------@using the target's AIS pointer as the only argument
bl				0x08067D14
b				0x0805788A
lsl	r0,	r0,	#0x0	@
.long				0x0000010D
.org				0x08057854
add	r0,	r6,	#0x0	@
add	r0,	#0x1C		@
cmp	r1,	r0		@Check if frame is 0x2C
bne				0x0805786E
@-------------------------------@The animation cannot complete if this frame is looped
str	r7,	[sp,	#0x0]	@These
str	r7,	[sp,	#0x4]	@two lines zero some local variables
add	r0,	r5,	#0x0	@
mov	r1,	#0x0		@
mov	r2,	#0xE		@
mov	r3,	#0x10		@
@-------------------------------@Not sure what this routine does but seems unnecessary
bl				0x08055F08
b				0x0805788A
.org				0x0805786E
add	r0,	r6,	#0x0	@
add	r0,	#0x32		@
cmp	r1,	r0		@Check if frame is 0x42 (unused >.>)
beq				0x0805788A
add	r0,	#0x5		@Below: Check if frame is 0x47
cmp	r1,	r0		@-----through here are animation specific checks of the current frame ID
@-------------------------------@for calling routines responsible for the special effects unique to
@-------------------------------@each animation; except for the difference in registers popped and the
@-------------------------------@odd stack write related SP increment the SoS animation does, the rest of
@-------------------------------@this routine is paraphrased in the Divine animation routine
bne				0x0805788A
@-------------------------------@Terminate spell animation and allow caster to continue
bl				0x0804FFFC
bl				0x0804FBC4
add	r0,	r4,	#0x0	@
bl				0x080046A0
.org				0x0805788A
add	sp,	#0x8		@
pop	{r4-r7}			@
pop	{r0}			@
bx	r0			@Sword of Seals complete!

@-------------------------------@Divine
.org				0x0805AECC
@-------------------------------@Compared within to the SoS doc above

.org				0x0805B246
ldr	r0,	[pc,	#0x14]	@=#0x08242348
@-------------------------------@Loads a sheet for part of the Divine animation

.org				0x08057894
push	{r4-r5, lr}		@
add	sp,	#-0x4		@
mov	r5,	r0		@
ldr	r1,	[pc,	#0x50]	@=#0x0201774C
ldr	r0,	[r1]		@
add	r0,	#0x1		@
str	r0,	[r1]		@
ldr	r0,	[pc,	#0x4C]	@=#0x08BA188C - PC list
mov	r1,	#0x3		@
bl				0x08004494
mov	r4,	r0		@
str	r5,	[r4,	#0x5C]	@
mov	r0,	#0x0		@
strh	r0,	[r4,	#0x2C]	@
mov	r0,	#0x34		@
strh	r0,	[r4,	#0x2E]	@
mov	r0,	r5		@
bl				0x08054678
ldr	r3,	[pc,	#0x34]	@=#0x08BA7F18 - Vector of OAM pointers (left to right)
cmp	r0,	#0x0		@
bne				0x08057C84
ldr	r3,	[pc,	#0x34]	@=#0x08BA72B8 - Vector of OAM pointers (right to left)
.org				0x08057C84
str	r3,	[sp]		@
mov	r0,	r5		@
mov	r1,	r3		@
bl				0x0805041C
str	r0,	[r4,	#0x60]	@
ldr	r0,	[pc,	#0x28]	@=#0x081EF21C - Palette data
mov	r1,	#0x20		@32 bytes in a palette
bl				0x080505F0
ldr	r0,	[pc,	#0x24]	@=#0x081EE51C - Sheet data (limited to 128 tiles)
mov	r1,	#0x80		@128 tiles
lsl	r1,	r1,	#0x5	@32 bytes per tile
bl				0x080505C8
add	sp,	#0x4		@
pop	{r4, r5}		@
pop	{r0}			@
bx	r0			@*Whew* SoS graphic loading complete!

Parts of a spell animation:

- Constructor
	Universal initialization and loads a callback to univeral processor
	Need: auto-patching and editor support
- Universal processor
	Accommodates the below
	Need: auto-patching and editor support
- Sound
	Handled by hack in section below
	Need: auto-patching and editor support
- BG transparency
	Have an unused command set transparency (0x29)
	Complete
- Toggling map2/map3 viewability
	Have an unused command set "enabled" flags (0x2A)
	Complete
- Optional parts
	Have terminator with parameter formated as 8000XX00 (XX is parameter) exit animation if and
		only if XX is 00 or if the animation will miss
	Complete
- Other commands
	Handled normally
	Complete
- Background layer (main part of animation)
	Custom frame command 0x86 to also load BG frame tiles with OAM
	Formatted as [byte - duration] 00 [byte - frame #] 86 [word - sheet pointer for OAM]
		[word - OAM offset] [word - BG OAM offset] [word - sheet pointer for BG layer]
	Note: To cover the screen, the game usually has the sheet be a vertically compressed version of
		the image to display and then stretches the map
		Sheet size is 256x64 (as usual)
		Map size is 240x64
		Display size is 240x120, so stretch is 15:8
	Need: info on processing battle animation formatted OAM into real OAM (hijack a call?)
- OAM (sheet coords/dimensions unknown; seems to use a separate sheet from BG layer)
	Processed by 0x86 commands normally except the sheet needs to be located elsewhere and the
		resulting OAM needs to have a different base offset for which tile to use
	Need: see above; also need to know how to handle priority changing
- Frame data
	Formatted as usual; and then 2 more words with pointers to piercing OAM and a BG sheet after
	Need: editor implementation
- Screen scrolling
	Use 0x85 command 0x40 to call the function for this (notes on how above)
	Complete
- Screen dimming
	Notes above
	Complete

To process:
- All PCs in the spell animation PC table pointing to constructor to point to the same "universal
constructor" if for a CSA
- New animation table format:
typedef struct
{
	//No 12 byte name
	//No section data (only one mode)
	frameData * frameDataRef;
	OAMdata * rightToLeftOAM;
	OAMdata * lefToRightOAM;
	OAMdata * rightToLeftBGOAM;
	OAMdata * lefToRightBGOAM;
	//The following 2 are deprecated and will be hardcoded
	//because all sheets will be designed as covering the entire screen
	//TSAdata * rightToLeftTSA;
	//TSAdata * leftToRightTSA;
	palette * paletteRef;
} animatonData;
written to some free space with
byte processStream[] = new byte[]
{
	25, 0, 0, 0,
	3, 0, 0, 0,
	(byte) AUTO_PATCH_ADDR,
	(byte) AUTO_PATCH_ADDR >> 8,
	(byte) AUTO_PATCH_ADDR >> 16,
	(byte) AUTO_PATCH_ADDR >> 24,
	0, 0, 0, 0,
	0, 0, 0, 0
}
prior
- New 0x86 command format:
typedef struct
{
	byte duration;
	byte empty;
	byte frameID;
	byte x86ID;
	sheet * spriteGFX;
	int OAMoffset;
	int BGOAMoffset;
	sheet * map1GFX;
} frame;
- Hardcoded right to left and left to right TSA written to some other free space
- Write all sheets as compressed and write all OAM and frame data as uncompressed
- Have PC loaded from table for custom spells initialize some free space with pointers to where in the ROM to process the animation from; check which side of the screen the attacker is on and offset the
pointers accordingly; also have this routine point to the struct with the processor callback point
to one containing a PC for the universal processing code
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//////////////////////////////
Sound effect commands have 0x19 subtracted from their value and are then left shifted twice
to be used as an offset for a PC table that is located at 0x08067864

Command IDs are read from 0x02028F1D for the unit on the right

.org				0x08067842
sub	r0,	#0x19		@
ldr	r2,	[sp]		@
cmp	r0,	#0x37		@0x19 + 0x37 =  0x50
bls				0x0806784C
b				0x08067AEA
.org				0x0806784C
lsl	r0,	r0,	#0x2	@
ldr	r1,	[pc,	#0x10]	@=#0x08067864
add	r0,	r0,	r1	@
ldr	r0,	[r0]		@
mov	r15,	r0		@

This is responsible for loading the actual music ID for the sound

.org				0x08067A1E
ldr	r1,	[pc,	#0x14]	@=#0x08BDB328
lsl	r0,	r7,	#0x2	@Origin of r7 unknown
add	r0,	r0,	r1	@
ldr	r1,	[r0]		@
lsl	r0,	r2,	#0x1	@
add	r0,	r0,	r5	@Don't know where this came from either
lsl	r0,	r0,	#0x1	@
add	r0,	r0,	r1	@
ldrh	r4,	[r0]		@Loads music ID
b				0x08067AEC

Perhaps hacking one of the unused commands to be treated as a sound command with the bytes for the
music ID in the 2 unused bytes of the command is the best way to handle SFX in a dynamic spell animation

The above ASM occurred for command 0x1B, so the PC for sound command 0x1B should be used and the
associated ASM modified to accomplish the above

Hack to realize 85 00 00 48 as "85 XX YY 48 - Play music of ID XXYY":

@Hook
.org				0x08067920
@-------------------------------@Target address
.long				0x080CB554

.org				0x080CB554
add	sp,	#0x1C		@B007
ldr	r4,	[sp,	#0x0]	@9C00; Get pointer to interpretation phase data
add	sp,	#-0x1C		@B087
ldr	r4,	[r4,	#0x20]	@6A24; Get pointer to next frame to interpret
sub	r4,	#0x4		@3C04
ldr	r4,	[r4]		@6824; Load command being executed
lsl	r4,	r4,	#0x8	@0224
lsr	r4,	r4,	#0x10	@0C24; Extract music ID
ldr	r0,	[pc,	#0x0]	@4800
bx	r0			@4700; Branch to play routine
@.align				2
.org				0x080CB568
.long				0x08067AED
.org				0x080CB56C
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//////////////////////////////
Animation interpreter structs

0x48 bytes in size

0x02028E78 - Left unit's struct
0x02028F08 - Right unit's struct

+0x00	Flag byte
		AND 0x02: True when cape flowing? Acts as though AND 0x01 is false?
		AND 0x01: True to display sprites/continue animation
+0x02	X offset based on screen scroll
+0x06	Byte of delay countdown
+0x08	Halfword of basis for part 2 of 0-2 of OAM data (which selects which tile is the top left corner)
		0x9B00 for right unit (name = 0x300; tile 768 where the sheet is loaded to)
+0x13	Byte of frame ID
+0x15	Byte of ID of 0x85 command being executed
+0x20	Frame pointer
+0x24	Pointer to last 0x86 command?
+0x30	OAM start pointer
+0x34	Parent AIS (drawn before this one)
+0x38	Child AIS (drawn after this one)
+0x3C	OAM pointer

Located at 0x02028F98 and 0x48 bytes in size - spell data struct for left unit?

To initialize both AISs:

R00	Mode for left unit (immediate 8)
R01	Mode for right unit (immediate 8)
Call	0x080542D8

To initialize an AIS:

0x02000060 = ROM pointer of section data (The location this has to be at may be changed; see below)
R00	Mode (0 based; modes are labeled with 1 as the base in these notes) (Should be 8)
Call	0x08054474 - Will use right unit addresses; this will need to be remedied by copying the
	function to elsewhere and modifying the constants

.org				0x080064CC
bl				0x08006688
@-------------------------------@Seems to be the only location of this call

To process the current frame of an animation:

@R00 == Pointer to animation interpreter struct
bl				0x08006688
@Returns a boolean of unknown purpose
@Updates sheet and OAM pointers in the struct or queues an 0x85 command
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
